package com.yunhe.option.service.data.impl;

import com.yunhe.option.domain.data.PushConfig;
import com.yunhe.common.exception.ObjectNotFoundException;
import com.yunhe.option.repository.data.PushConfigRepository;
import com.yunhe.option.service.data.PushConfigService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

@Service
public class PushConfigServiceImpl implements PushConfigService {

    @Autowired
    private PushConfigRepository pushConfigRepository;

    @Override
    public PushConfig createPushConfig(PushConfig pushConfig) {
        return pushConfigRepository.save(pushConfig);
    }

    @Override
    public void deletePushConfig(String name) {
        pushConfigRepository.deleteById(name);
    }

    @Override
    public PushConfig updatePushConfig(String name,
                                       Integer receiveMsg,
                                       Integer voice,
                                       Integer shock,
                                       Integer charge,
                                       Integer alarm,
                                       Integer alarmClear)
            throws ObjectNotFoundException {
        PushConfig config = findByName(name);
        if (config == null) {
            config = new PushConfig();
            config.setName(name);
            config.setAlarm(1);
            config.setAlarmClear(1);
            config.setCharge(1);
            config.setReceiveMsg(1);
            config.setShock(1);
            config.setVoice(1);
            pushConfigRepository.save(config);
//            throw new ObjectNotFoundException("找不到账号为" + name + "的配置");
        }
        Optional.ofNullable(receiveMsg).ifPresent(config::setReceiveMsg);
        Optional.ofNullable(voice).ifPresent(config::setVoice);
        Optional.ofNullable(shock).ifPresent(config::setShock);
        Optional.ofNullable(charge).ifPresent(config::setCharge);
        Optional.ofNullable(alarm).ifPresent(config::setAlarm);
        Optional.ofNullable(alarmClear).ifPresent(config::setAlarmClear);
        return pushConfigRepository.save(config);
    }

    @Override
    public PushConfig findPushConfig(String name) {
        PushConfig config = findByName(name);
        if (config == null) {
            config = new PushConfig();
            config.setName(name);
            config.setAlarm(1);
            config.setAlarmClear(1);
            config.setCharge(1);
            config.setReceiveMsg(1);
            config.setShock(1);
            config.setVoice(1);
            return pushConfigRepository.save(config);
        }
        return config;
    }

    @Override
    public List<PushConfig> findPushConfig(String name,
                                           Integer alarm,
                                           Integer alarmClear,
                                           Integer charge) {
        Specification spec = (root, query, cb) -> {
            List<Predicate> list = new ArrayList<>();
            if (StringUtils.isNotEmpty(name)) {
                list.add(cb.equal(root.get("name"), name));
            }
            if (alarm != null) {
                list.add(cb.equal(root.get("alarm"), alarm));
            }
            if (alarmClear != null) {
                list.add(cb.equal(root.get("alarmClear"), alarmClear));
            }
            if (charge != null) {
                list.add(cb.equal(root.get("charge"), charge));
            }
            if (list.size() == 1) {
                query.where(list.get(0));
            } else {
                query.where(list.toArray(new Predicate[0]));
            }
            return null;
        };
        return pushConfigRepository.findAll(spec);
    }

    private PushConfig findByName(String name) {
        return pushConfigRepository.findById(name).orElse(null);
    }
}
